module Forward (forward) where

import DirectApproach
import Array

-- Forward algorithm
-- The forward variable is defined next as well as its auxiliary function to compute 
-- summations
alpha :: HMM a -> [Int] -> Int -> Int -> Float
alpha hmm (x:xs) 1 i 	= (initDiHMM hmm)!i * (pObsHMM hmm)!(i, x)
alpha hmm xs t i 		= (auxAlpha hmm xs t (rangeSize (bounds (statesHMM hmm))) i) * 
						  (pObsHMM hmm)!(i, last xs)

auxAlpha :: HMM a -> [Int] -> Int -> Int -> Int -> Float
auxAlpha hmm xs t 1 i 	= (alpha hmm (init xs) (t-1) 1) * (pTransHMM hmm)!(1,i)
auxAlpha hmm xs t m i	= (alpha hmm (init xs) (t-1) m) * (pTransHMM hmm)!(m,i) +
						  (auxAlpha hmm xs t (m-1) i)

-- The actual probability is computed here
forward :: HMM a -> [Int] -> Float
forward hmm xs = auxForward hmm xs (rangeSize (bounds (statesHMM hmm)))

-- This auxiliary functions calls the forward variable alpha and computes the corresponding summations 
auxForward :: HMM a -> [Int] -> Int -> Float
auxForward hmm xs 1 = alpha hmm xs (length xs) 1
auxForward hmm xs i = (alpha hmm xs (length xs) i) + (auxForward hmm xs (i-1))